<?php

/**
 * Author：晴玖天
 * Creation：2020/4/6 15:23
 * Filename：GoodsCart.php
 * 简单购物车操作类
 */

namespace extend;


use config;
use lib\Hook\Hook;
use login_data;
use Medoo\DB\SQL;

class GoodsCart
{

    /**
     * @param $DataArr
     * 开始提交购物车订单[如果有商品无法结算，直接拦截全部]
     */
    public static function CartPay($DataArr = [], $type = 1, $mode = 'alipay', $CartKey = -1)
    {
        global $conf;
        $UserData = login_data::user_data();
        $Array = self::CartList($DataArr, $CartKey, $UserData, 2);
        if (count($Array['data']) == 0) {
            dies(-1, '没有可结算的商品，请先去购物车添加点商品吧！');
        }
        //开始结算购物车订单【新结算模式】
        if ($type == 1) {
            //在线支付【创建订单缓存批量结算，需要先验证商品是否可以完成下单！】
            dies(-2, '暂不支持在线支付结算购物车商品，仅支持余额或积分兑换!');
        } else {
            //余额或积分支付【一个个单独结算，结算完一个就提交一个】
            $conf['OrderAstrict'] = 0;
            $SuccessId = [];
            $ErrorMsg = [];
            foreach ($Array['data'] as $key => $val) {
                $Res = Buy::OrderSubmit($val['GidData']['goods'], [
                    'type' => $type,
                    'data' => $val['input'],
                    'num' => $val['num'] - 0,
                    'mode' => $mode,
                ], 1);
                if ($Res['code'] == 1) {
                    $SuccessId[] = $val['id'];
                } else {
                    //失败订单，取出原因
                    $ErrorMsg[] = [
                        'id' => $key,
                        'GidData' => $val['GidData'],
                        'msg' => $Res['msg']
                    ];
                }
            }
            if (count($SuccessId) >= 1) {
                //清理购物车商品[已完成的]
                self::CartDet($SuccessId, 2);
            }
            $Msg = [];
            foreach ($ErrorMsg as $value) {
                $Msg[] = '<span style="color: red">' . $value['GidData']['name'] . ' - ' . $value['GidData']['goods']['num'] . ' ' . $value['GidData']['goods']['units'] . '：' . $value['msg'] . '</span>';
            }
            if (count($Msg) === 0) {
                $Msg[] = '无结算失败商品！';
            } else {
                $Msg[] = '已帮您将结算失败的商品放回到购物车！';
            }
            dier([
                'code' => 1,
                'msg' => '<div style="text-align: center">结算完成，共有' . count($Array['data']) . '个待结算商品<br>其中结算成功了' . count($SuccessId) . '个商品！<br>失败了' . count($ErrorMsg) . '个商品！<br>失败原因：<br>' . implode('<br />', $Msg) . '</div>',
                'successId' => $SuccessId,
                'errorMsg' => $ErrorMsg
            ]);
        }
    }

    /**
     * @param array $array
     * @param int $Type //1=购物车列表，2=购物车结算
     * @return array
     * 取出购物车订单列表[重构一下，调用通用价格获取方法]
     */
    public static function CartList($array = [], $CartKey = -1, $User = -2, $Type = 1)
    {
        global $conf;
        $DB = SQL::DB();
        if ($User == -2) {
            $User = login_data::user_data();
        }
        $Res = self::CartContent($CartKey, $User);
        if ($Res['code'] != 1) {
            return $Res;
        }
        $DataArr = $Res['data']; //购物车参数赋值
        $UnsetKey = []; //无效购物车参数标记
        $GoodsCountList = []; //单商品总下单数量计算
        $DataList = []; //商品数据
        foreach ($DataArr as $key => $value) {
            //计算单商品总下单数量
            if (empty($GoodsCountList[$value['gid']])) {
                $GoodsCountList[$value['gid']] += $value['num'];
            } else {
                $GoodsCountList[$value['gid']] = $value['num'];
            }
            $Goods = Buy::GetProductInformation([
                'gid' => $value['gid'],
                'num' => $value['num'],
                'data' => $value['input'],
            ]);
            if ($Goods['code'] <= 0) {
                $DataArr[$key]['conts'] = $Goods['msg'];
                $Goods = $DB->get('goods', '*', ['gid' => $value['gid']]);
                if (!$Goods) {
                    //商品不存在！【需要清理】
                    $UnsetKey[] = $key;
                    continue;
                }
                //库存不足或者各种异常问题
                $Goods['price'] = 99999999;
                $Goods['points'] = 99999999;
                $Goods['quota'] = 0; //库存归零
                $Goods['num'] = $value['num'];
                $CartState = 2;
            } else {
                //正常商品
                $Goods = $Goods['data'];
                $CartState = 1;
            }
            if (!is_array($Goods['image'])) {
                $Goods['image'] = json_decode($Goods['image'], true);
            }
            $DataList[$key] = [
                'gid' => $Goods['gid'] - 0,
                'name' => $Goods['name'],
                'image' => $Goods['image'][0] ?? href(2) . '/assets/img/404.png',
                'price' => $Goods['price'],
                'points' => $Goods['points'],
                'cid' => $Goods['cid'] - 0,
                'count_type' => ((!in_array(7, json_decode($Goods['method'], TRUE))) ? -1 : 1), //是否可以下单多份
                'min' => $Goods['min'] - 0,
                'max' => $Goods['max'] - 0,
                'quota' => $Goods['quota'],
                'quantity' => $Goods['quantity'] - 0,
                'communityId' => $Goods['deliver'],
                'method' => $Goods['method'],
                'step' => 1,
            ];
            if ($Type == 2) {
                $DataList[$key]['goods'] = $Goods;
                $DataList[$key]['cart_state'] = $CartState;
            }
        }
        //删除无效购物车商品
        if (count($UnsetKey) >= 1) {
            self::CartDet($UnsetKey, 2);
        }
        $Data = [];
        foreach ($DataArr as $k => $v) {
            if (in_array($k, $UnsetKey)) {
                //去除已清理的购物车商品
                continue;
            }
            $v['GidData'] = $DataList[$k];
            $v['GidData']['Count'] = $GoodsCountList[$v['gid']];
            if (empty($v['conts'])) {
                $v['conts'] = '无下单信息';
            }
            $Data[] = $v;
        }

        $Ap = 0; //免费商品总数
        if (count($array) >= 1) {
            $DataGoods = [];
            foreach (array_reverse($Data) as $key => $value) {
                if (!in_array($key, $array)) continue;
                if ($value['GidData']['price'] == 0 || $value['GidData']['points'] == 0) {
                    ++$Ap;
                }
                $DataGoods[] = $value;
            }
            $Data = array_reverse($DataGoods);
        }
        return [
            'code' => 1,
            'msg' => '购物车内共有' . count($Data) . '款有效商品!',
            'data' => $Data,
            'count' => count($Data),
            'sitename' => $conf['sitename'],
            'Charge' => $Ap,
        ];
    }

    /**
     * @param $id
     * @param int $type
     * 移出购物车！删除
     */
    public static function CartDet($id, $type = 1)
    {
        $re = self::CartContent();
        if ($re['code'] != 1) dies(-1, '操作失败,购物车空空如也!');
        $a = 0;
        $Data = [];

        foreach ($re['data'] as $v) {
            if ($type == 1) {
                if ($a != $id) {
                    $Data[] = $v;
                }
            } else {
                if (!in_array($a, $id)) {
                    $Data[] = $v;
                }
            }
            ++$a;
        }
        $res = self::CartAddEdit(serialize(array_reverse($Data)), $re['id']);
        if ($res === true) {
            Hook::execute('CartDel', [
                'id' => $re['id'],
                'data' => $Data
            ]);
            if ($type === 1) {
                dies(1, '移出购物车成功！');
            } else return true;
        }

        if ($type === 1) {
            dies(1, '移出购物车失败！');
        } else {
            return false;
        }
    }

    /**
     * 删除全部购物车商品
     */
    public static function DeleteAll()
    {
        $re = self::CartContent();
        if ($re['code'] != 1) dies(-1, '操作失败,购物车空空如也!');
        $Data = [];
        $List = $re;
        foreach ($List['data'] as $Key => $Value) {
            $Data[] = $Key;
        }
        if (GoodsCart::CartDet($Data, 2) === true) {
            dies(1, '购物车清空成功！');
        } else {
            dies(-1, '购物车清空失败！');
        }
    }

    /**
     * 取出购物车原始数据+数据ID
     */
    public static function CartContent($CartKey = -1, $User = -2)
    {
        $DB = SQL::DB();
        if ($User == -2) {
            $User = login_data::user_data();
        }
        if (!$User) {
            if ($CartKey != -1 && $CartKey != '' && strlen($CartKey) == 32) {
                //指定购物车cookie参数值[用于接口对接]
                $_COOKIE['CartKey'] = $CartKey;
            }
            if (!empty($_COOKIE['CartKey'])) {
                if (strlen($_COOKIE['CartKey']) != 32) {
                    setcookie('CartKey', '', time() - 3600, '/');
                    return [
                        'code' => -2,
                        'msg' => '购物车空空如也',
                    ];
                }
                $CartData = $DB->get('cart', '*', [
                    'cookie' => (string)$_COOKIE['CartKey']
                ]);
                if (!$CartData) {
                    return [
                        'code' => -2,
                        'msg' => '购物车空空如也',
                    ];
                }
            } else {
                return [
                    'code' => -2,
                    'msg' => '购物车空空如也',
                ];
            }
        } else {
            $CartData = $DB->get('cart', '*', [
                'uid' => (int)$User['id']
            ]);
            if (!$CartData) {
                return [
                    'code' => -2,
                    'msg' => '购物车空空如也',
                ];
            }
        }
        $DataArr = config::common_unserialize($CartData['content']);
        if (!is_array($DataArr)) {
            $DataArr = [];
        }
        if (count($DataArr) == 0) {
            return [
                'code' => -2,
                'msg' => '购物车空空如也',
            ];
        }
        $List = [];
        //array_reverse() 内置方法貌似有点问题，会导致索引异常，导致排序错误？
        foreach ($DataArr as $k => $v) {
            $id = (count($DataArr) - 1) - $k;
            $v['id'] = $id;
            $List[$id - 0] = $v;
        }
        ksort($List);
        return [
            'code' => 1,
            'id' => $CartData['id'] - 0,
            'data' => $List, //商品顺序从新到旧
        ];
    }

    /**
     * @param string $Content
     * @param $id //购物车订单编号
     * 更新购物车数据！
     */
    public static function CartAddEdit($Content, $id)
    {
        $DB = SQL::DB();
        $Res = $DB->update('cart', [
            'content' => $Content
        ], [
            'id' => $id
        ]);
        if ($Res) {
            return true;
        }
        return false;
    }

    /**
     * @param $Data
     * 购物车商品下单数量调整
     */
    public static function CartNum($Data)
    {
        $DB = SQL::DB();
        if ((int)$Data['num'] <= 0) {
            dies(-1, '下单份数异常！');
        }
        $kid = (int)$Data['id'];
        $DataCart = self::CartContent();
        if ($DataCart['code'] != 1) {
            dies(-1, '购物车空空如也！');
        }
        $Datas = [];
        $a = 0;
        foreach ($DataCart['data'] as $v) {
            if ($kid == $a) {
                $data_v = $v;
                $Goods = $DB->get('goods', '*', ['gid' => (int)$v['gid'], 'state' => 1]);
                if (!$Goods) {
                    dies(-1, '商品不存在或已下架');
                }

                if (in_array(7, json_decode($Goods['method'], TRUE))) {
                    $Goods['min'] = 1;
                    $Goods['max'] = 1;
                }

                if (empty($Goods['min'])) {
                    $Goods['min'] = 1;
                }
                if (empty($Goods['max'])) {
                    $Goods['max'] = 1;
                }

                if ($Data['num'] < $Goods['min']) {
                    dies(-1, '当前商品最低购买' . $Goods['min'] . '份！');
                }

                if ($Data['num'] < $Goods['max']) {
                    dies(-1, '当前商品最多购买' . $Goods['max'] . '份！');
                }

                $price = $data_v['price'] / $data_v['num'];


                $Num = $Data['num'];
                $Pirc = round($price * $Num, 8);
                $data_v['num'] = $Num;
                $data_v['price'] = $Pirc;
                $Datas[] = $data_v;
            } else {
                $Datas[] = $v;
            }
            ++$a;
        }
        $res = self::CartAddEdit(serialize(array_reverse($Datas)), $DataCart['id']);
        if ($res) dies(1, '调整成功！');
        dies(-1, '调整失败！');
    }

    /**
     * @param $Data
     * 添加购物车【重构日期：2023/6/9】
     */
    public static function CartAdd($Data)
    {
        $DB = SQL::DB();
        $User = login_data::user_data();
        if (!$Data['CouponId']) {
            $Data['CouponId'] = -1;
        }
        $Goods = Buy::GetProductInformation($Data, $User);
        if ($Goods['code'] != 1) {
            dies(-1, $Goods['msg']);
        }
        $Goods = $Goods['data'];
        if (empty($Data['conts'])) {
            $Input = [];
            foreach (explode('|', $Goods['input']) as $value) {
                if (strpos($value, '{') !== false && strpos($value, '}') !== false) {
                    $Input[] = explode('{', $value)[0];
                } else {
                    $Input[] = $value;
                }
            }
            if ((int)$Goods['specification'] === 2) {
                $SpRule = RlueAnalysis($Goods, 3);
                if ($SpRule !== -1) {
                    $Input = array_merge($SpRule['MasterRule'], $Input);
                }
            }
            $is = 0;
            foreach ($Data['data'] as $v) {
                $NameInput = TakeMultipleNames((empty($Input[$is]) ? '输入框' . ($is + 1) : $Input[$is]));
                $Data['conts'] .= $NameInput . '：' . $v . ' ';
                ++$is;
                unset($NameInput);
            }
        }
        if (strlen($_COOKIE['CartKey']) != 32) {
            setcookie('CartKey', '', time() - 1, '/');
            $_COOKIE['CartKey'] = null;
        }
        $SQL = [
            'cookie' => $_COOKIE['CartKey'],
            'uid' => -1,
        ];
        $CookieKey = md5(time() . userip() . random_int(1000, 9999999));
        if ($User) {
            $CookieKey = null;
            unset($SQL['cookie']);
            $SQL['uid'] = (int)$User['id'];
        } else {
            unset($SQL['uid']);
        }
        $GetCart = $DB->get('cart', '*', $SQL);
        $Content = [[
            'gid' => $Goods['gid'],
            'input' => $Data['data'],
            'num' => $Goods['num'],
            'conts' => $Data['conts'],
            'price' => $Goods['price'],
        ]];
        if (!$GetCart) {
            if (!empty($_COOKIE['CartKey'])) {
                setcookie('CartKey', '', time() - 1, '/');
            }
            $Res = self::CartEstablish((empty($CookieKey)) ? $User['id'] : -1, $CookieKey, serialize($Content));
        } else {
            $CartList = config::common_unserialize($GetCart['content']);
            if (count($CartList) >= 1) {
                $CartData = [];
                $State = 1;
                foreach ($CartList as $value) {
                    if ($value['gid'] == $Goods['gid'] && $value['input'] == $Data['data'] && in_array(7, json_decode($Goods['method'], TRUE))) {
                        $State = 2;
                        $CartData[] = [
                            'gid' => (int)$Goods['gid'],
                            'input' => $Data['data'],
                            'num' => (int)$Goods['num'] + (int)$value['num'],
                            'conts' => $Data['conts'],
                            'price' => $Goods['price'] + (float)$value['price'],
                        ];
                        //商品购买数量限制拦截
                        if (((int)$Goods['num'] + (int)$value['num']) > $Goods['max']) {
                            dies(-1, '当前商品最多购买' . $Goods['max'] . '份！');
                        }
                    } else {
                        $CartData[] = $value;
                    }
                }
                if ($State === 1) {
                    $Content = array_merge($CartList, $Content);
                } else {
                    $Content = $CartData;
                }
            }
            $Res = self::CartAddEdit(serialize($Content), $GetCart['id']);
        }
        if ($Res) {
            if (!empty($CookieKey)) {
                if (empty($_COOKIE['CartKey'])) {
                    setcookie('CartKey', $CookieKey, time() + 31536000, '/');
                } else {
                    setcookie('CartKey', $_COOKIE['CartKey'], time() + 31536000, '/');
                }
            }
            Hook::execute('CartAdd', [
                'gid' => $Goods['gid'],
                'input' => $Data['data'],
                'num' => $Goods['num'],
                'conts' => $Data['conts'],
                'price' => $Goods['price'],
            ]);
            dier([
                'code' => 1,
                'msg' => '已经成功添加到购物车!',
                'count' => count($Content),
            ]);
        } else {
            dies(-1, '购物车添加失败！');
        }
    }

    /**
     * @param int $Uid 用户ID
     * @param null $CartKey 缓存ID
     * @param array $Content 商品序列化信息！
     * 创建购物车订单,新增！
     */
    public static function CartEstablish($Uid = -1, $CartKey = null, $Content = '')
    {
        global $date;
        $DB = SQL::DB();
        $Res = $DB->insert('cart', [
            'uid' => $Uid,
            'cookie' => $CartKey,
            'content' => $Content,
            'ip' => userip(),
            'addtime' => $date
        ]);
        if ($Res) {
            return true;
        }
        return false;
    }

    /**
     * @return int
     * 获取当前用户购物车商品数量
     */
    public static function CartCount()
    {
        $DB = SQL::DB();
        $User = login_data::user_data();
        if (!$User) {
            if (empty($_COOKIE['CartKey'])) {
                return 0;
            }
            if (strlen($_COOKIE['CartKey']) != 32) {
                setcookie('CartKey', '', time() - 1, '/');
                return 0;
            }
            $re = $DB->get('cart', ['content'], [
                'cookie' => (string)$_COOKIE['CartKey']
            ]);
        } else {
            $re = $DB->get('cart', ['content'], [
                'uid' => (int)$User['id']
            ]);
        }
        if (!$re) {
            return 0;
        }
        $DataArr = config::common_unserialize($re['content']);
        return count($DataArr);
    }

    /**
     * @param $Uid //用户编号
     * 将未登录用户购物车的缓存数据，添加到已登录用户中！
     */
    public static function UserCookieDer($Uid)
    {
        global $date;
        $DB = SQL::DB();
        $DB->update('user', [
            'recent_time' => $date,
        ], [
            'id' => $Uid
        ]);

        if (!empty($_COOKIE['CartKey'])) {
            $Cookey = $_COOKIE['CartKey'];
            setcookie("CartKey", "", time() - 3600 * 24 * 30 * 12, '/');
            if (strlen($Cookey) <> 32) dies(-1, '购物车缓存参数异常,请手动清除Cookie！');
            $res = $DB->get('cart', '*', [
                'cookie' => (string)$Cookey
            ]);
            if (!$res) return false;
            $re = $DB->get('cart', '*', [
                'uid' => (int)$Uid
            ]);
            if ($re) {
                $DataArr1 = config::common_unserialize($res['content']);
                $DataArr2 = config::common_unserialize($re['content']);
                $DataArr3 = array_merge($DataArr2, $DataArr1);
                self::CartAddEdit(serialize($DataArr3), $re['id']);
                $DB->delete('cart', [
                    'id' => $res['id']
                ]);
            } else {
                $DB->update('cart', [
                    'uid' => $Uid,
                    'cookie' => ''
                ], [
                    'cookie' => $Cookey
                ]);
            }
            return true;
        } else return false;
    }
}
